<script setup>
import bwPowerSet from '@/utils/powerSet.js';
import { watchEffect, ref, defineEmits } from 'vue';
import { useDetailStore } from '@/stores/detail.js';
let pathMap = {};
const btnDisabled = ref(true);
const detailStore = useDetailStore();
const emit = defineEmits(['addCartSku-event']);
const addCartSku = ref(null);

const clickSpecs = (item, val) => {
	if (val.disabled) return;
	if (val.selected) {
		val.selected = false;
	} else {
		item.values.forEach((v) => {
			v.selected = false;
		})
		val.selected = !val.selected;
	}

	// 更新按钮状态
	const selectedArr = getSelectedArr(detailStore.goods.specs)
	const index = selectedArr.findIndex(item => item === undefined)
	if (index > -1) {
		btnDisabled.value = true;
		addCartSku.value = null;
	} else {
		btnDisabled.value = false;
		const key = selectedArr.join('-');
		addCartSku.value = detailStore.goods.skus.find(sku => sku.id === pathMap[key][0])
		emit('addCartSku-event', addCartSku);
	}
	updateDisabledStatus(detailStore.goods.specs, pathMap);
}

// 生成有效路径字典对象
const getPathMap = (skus) => {
	const pathMap = {};
	// 1. 过滤掉无效的sku
	const effectiveSkus = skus.filter(sku => sku.inventory > 0);
	// 2. 生成路径字典对象(子集算法)[1,2] => [[1],[2],[1,2]]
	effectiveSkus.forEach(sku => {
		// 2.1获取匹配的valueName组成数组
		const selectedValArr = sku.specs.map(spec => spec.valueName)

		// 2.2 计算子集
		const valueArrPowerSet = bwPowerSet(selectedValArr);

		// 3. 把生成的子集生成路径字典对象
		valueArrPowerSet.forEach(arr => {
			const key = arr.join('-');
			if (!pathMap[key]) {
				pathMap[key] = [sku.id];
			} else {
				pathMap[key].push(sku.id);
			}
		})
	})
	return pathMap;
}

// 初始化禁用状态
const initDisabledStatus = (specs, pathMap) => {
	specs.forEach(spec => {
		spec.values.forEach(val => {
			if (pathMap[val.name]) {
				val.disabled = false;
			} else {
				val.disabled = true;
			}
		})
	})
}
// 获取选中项的匹配数组
const getSelectedArr = (specs) => {
	const selectedArr = [];
	specs.forEach(spec => {
		const selectedVal = spec.values.find(val => val.selected);
		if (selectedVal) {
			selectedArr.push(selectedVal.name);
		} else {
			selectedArr.push(undefined);
		}
	})
	return selectedArr;
}

//切换时更新禁用状态
const updateDisabledStatus = (specs, pathMap) => {
	specs.forEach((spec, index) => {
		const selectedArr = getSelectedArr(specs);
		spec.values.forEach(val => {
			selectedArr[index] = val.name;
			const key = selectedArr.filter(v => v).join('-');
			if (pathMap[key]) {
				val.disabled = false;
			} else {
				val.disabled = true;
			}
		})
	})
}

const addCartBtn = () => {
	if (addCartSku.value === null) return;
	emit('addCart', addCartSku);
}

watchEffect(() => {
	if (detailStore.goods.skus !== undefined) {
		pathMap = getPathMap(detailStore.goods.skus);
	}
	if (detailStore.goods.specs !== undefined)
		initDisabledStatus(detailStore.goods.specs, pathMap);
})

</script>
<template>
	<div class="goods-sku">
		<dl v-for="item in detailStore.goods.specs" :key="item.id">
			<dt>{{ item.name }}</dt>
			<dd>
				<template v-for="val in item.values" :key="val.name">
					<img :class="{ selected: val.selected, disabled: val.disabled }" @click="clickSpecs(item, val)"
						v-if="val.picture" :src="val.picture" />
					<span :class="{ selected: val.selected, disabled: val.disabled }" @click="clickSpecs(item, val)" v-else>{{
						val.name
					}}</span>
				</template>
			</dd>
		</dl>
	</div>
</template>

<style scoped lang="scss">
@mixin sku-state-mixin {
	border: 1px solid #e4e4e4;
	margin-right: 10px;
	cursor: pointer;

	&.selected {
		border-color: $xtxColor;
	}

	&.disabled {
		opacity: 0.6;
		border-style: dashed;
		cursor: not-allowed;
	}
}

.goods-sku {
	padding-left: 10px;
	padding-top: 20px;

	dl {
		display: flex;
		padding-bottom: 20px;
		align-items: center;

		dt {
			width: 50px;
			color: #999;
		}

		dd {
			flex: 1;
			color: #666;

			>img {
				width: 50px;
				height: 50px;
				margin-bottom: 4px;
				@include sku-state-mixin;
			}

			>span {
				display: inline-block;
				height: 30px;
				line-height: 28px;
				padding: 0 20px;
				margin-bottom: 4px;
				@include sku-state-mixin;
			}
		}
	}
}
</style>